package leetcode.code0691;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

import leetcode.IDebug;

public class Solution implements IDebug {

	public int minStickers(String[] stickers, String target) {
		char[] cs = target.toCharArray();
		// 每种贴纸的字符字典
		int[][] ss = new int[stickers.length][26];
		// 是否不足以满足target字符种类
		if (this.notEnough(cs, stickers, ss)) {
			// 是不足，返回-1
			return -1;
		}
		int len = cs.length;
		// 最多size种找到target找到状态
		int size = 1 << len;
		// 查看过的状态（入队的）
		boolean[] seen = new boolean[size];
		Queue<int[]> queue = new LinkedList<>();
		// queue(new int[]{需要找到字符位置，已用贴纸数量});
		queue.add(new int[] { size - 1, 0 });
		seen[size - 1] = true;
		while (!queue.isEmpty()) {
			int[] curs = queue.poll();
			int cur = curs[0], ans = curs[1] + 1;
			for (int[] s : ss) {
				// 尝试的贴纸
				int[] tmp = Arrays.copyOf(s, 26);
				// 重置当前需要的字符hash
				int nextAim = cur;
				int find = 0;
				int p = len - 1;
				while (nextAim > 0) {
					// 是所需要的字符
					if ((nextAim & 1) == 1) {
						int index = cs[p] - 'a';
						// 这个贴纸中有这个字符
						if (tmp[index] != 0) {
							// 计数减少一个
							tmp[index]--;
							// 找到一个
							find |= 1 << (len - 1 - p);
						}
					}
					nextAim >>= 1;
					p--;
				}
				// 有找到的可消除字符
				if (find > 0) {
					// 还有哪些没找到
					int next = cur ^ find;
					// 全部找到，返回最少纸条数量
					if (next == 0) {
						return ans;
					}
					if (!seen[next]) {
						seen[next] = true;// 没有这句...能看到用例83
						queue.add(new int[] { next, ans });
					}
				}
			}
		}
		return -1;
	}

	private boolean notEnough(char[] cs, String[] stickers, int[][] ss) {
		int cnt = 0;
		boolean[] dics = new boolean[26];
		for (int i = 0; i < cs.length; i++) {
			int index = cs[i] - 'a';
			if (!dics[index]) {
				dics[index] = true;
				cnt++;
			}
		}

		for (int i = 0; i < stickers.length; i++) {
			String sticker = stickers[i];
			for (char c : sticker.toCharArray()) {
				int index = c - 'a';
				if (dics[index]) {
					cnt--;
					dics[index] = false;
				}
				ss[i][index]++;
			}
		}
		return cnt != 0;
	}

	@Override
	public void debug4() {
		// TODO Auto-generated method stub

	}

	@Override
	public void debug3() {
		// TODO Auto-generated method stub

	}

	@Override
	public void debug2() {
		// TODO Auto-generated method stub

	}

	@Override
	public void debug1() {
		// TODO Auto-generated method stub

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
